package org.totoro.patterns.behavior.visitor;

/**
 * 访问者模式
 * <pre>
 * 此模式的优点就是，如果操作的逻辑改变，我们只需要改变访问者的实现就够了，而不用去修改其他所有的商品类。
 * 另一个好处是，添加新类别的商品到系统变得容易。只需要改变一下访问者接口以及其实现。已经存在的商品类别不会被干扰影响。
 * 当然，访问者模式的缺点也需要知道，visit()方法的返回值的类型在设计系统式就需要明确。不然，就需要修改访问者的接口以及所有接口实现。另外如果访问者接口的实现太多，系统的扩展性就会下降。
 * </pre>
 *
 * @see http://ifeve.com/visitor-design-pattern-in-java-example-tutorial/
 */
public class Client {

    public static void main(String[] args) {

        ItemElement[] items = new ItemElement[]{
                new Book(20, "1234"),
                new Book(100, "5678"),
                new Fruit(10, 2, "Banana"),
                new Fruit(5, 5, "Apple")
        };

        int total = calculatePrice(items);
        System.out.println("Total Cost = " + total);
    }

    private static int calculatePrice(ItemElement[] items) {

        ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();

        int sum = 0;

        for (ItemElement item : items) {
            sum = sum + item.accept(visitor);
        }
        return sum;
    }

}